home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
nt
/
lkbackup.zip
/
ct_tally.h
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-03
|
11KB
|
293 lines
#include <ctype.h>
/* ===========================================================================
* Constants */
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
#define MAX_BL_BITS 7
/* Bit length codes must not exceed MAX_BL_BITS bits */
#define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */
#define LITERALS 256
/* number of literal bytes 0..255 */
#define END_BLOCK 256
/* end of block literal code */
#define L_CODES (LITERALS+1+LENGTH_CODES)
/* number of Literal or Length codes, including the END_BLOCK code */
#define D_CODES 30
/* number of distance codes */
#define BL_CODES 19
/* number of codes used to transfer the bit lengths */
extern int extra_lbits[LENGTH_CODES]; /* extra bits for each length code */
extern int extra_dbits[D_CODES]; /* extra bits for each distance code */
extern int extra_blbits[BL_CODES];/* extra bits for each bit length code */
/* The three kinds of block type */
#ifndef LIT_BUFSIZE
# ifdef SMALL_MEM
# define LIT_BUFSIZE 0x2000
# else
# ifdef MEDIUM_MEM
# define LIT_BUFSIZE 0x4000
# else
# define LIT_BUFSIZE 0x8000
# endif
# endif
#endif
#ifndef DIST_BUFSIZE
# define DIST_BUFSIZE LIT_BUFSIZE
#endif
/* Sizes of match buffers for literals/lengths and distances. There are
* 4 reasons for limiting LIT_BUFSIZE to 64K:
* - frequencies can be kept in 16 bit counters
* - if compression is not successful for the first block, all input data is
* still in the window so we can still emit a stored block even when input
* comes from standard input. (This can also be done for all blocks if
* LIT_BUFSIZE is not greater than 32K.)
* - if compression is not successful for a file smaller than 64K, we can
* even emit a stored file instead of a stored block (saving 5 bytes).
* - creating new Huffman trees less frequently may not provide fast
* adaptation to changes in the input data statistics. (Take for
* example a binary file with poorly compressible code followed by
* a highly compressible string table.) Smaller buffer sizes give
* fast adaptation but have of course the overhead of transmitting trees
* more frequently.
* - I can't count above 4
* The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save
* memory at the expense of compression). Some optimizations would be possible
* if we rely on DIST_BUFSIZE == LIT_BUFSIZE.
*/
#if LIT_BUFSIZE > INBUFSIZ
error cannot overlay l_buf and inbuf
#endif
#define REP_3_6 16
/* repeat previous bit length 3-6 times (2 bits of repeat count) */
#define REPZ_3_10 17
/* repeat a zero length 3-10 times (3 bits of repeat count) */
#define REPZ_11_138 18
/* repeat a zero length 11-138 times (7 bits of repeat count) */
/* ===========================================================================
* Local data
*/
/* Data structure describing a single value and its code string. */
typedef struct ct_data {
union {
ush freq; /* frequency count */
ush code; /* bit string */
} fc;
union {
ush dad; /* father node in Huffman tree */
ush len; /* length of bit string */
} dl;
} ct_data;
#define Freq fc.freq
#define Code fc.code
#define Dad dl.dad
#define Len dl.len
#define HEAP_SIZE (2*L_CODES+1)
/* maximum heap size */
extern ct_data dyn_ltree[HEAP_SIZE]; /* literal and length tree */
extern ct_data dyn_dtree[2*D_CODES+1]; /* distance tree */
extern ct_data static_ltree[L_CODES+2];
/* The static literal tree. Since the bit lengths are imposed, there is no
* need for the L_CODES extra codes used during heap construction. However
* The codes 286 and 287 are needed to build a canonical tree (see ct_init
* below).
*/
local ct_data static_dtree[D_CODES];
/* The static distance tree. (Actually a trivial tree since all codes use
* 5 bits.)
*/
local ct_data bl_tree[2*BL_CODES+1];
/* Huffman tree for the bit lengths */
typedef struct tree_desc {
ct_data *dyn_tree; /* the dynamic tree */
ct_data *static_tree; /* corresponding static tree or NULL */
int *extra_bits; /* extra bits for each code or NULL */
int extra_base; /* base index for extra_bits */
int elems; /* max number of elements in the tree */
int max_length; /* max bit length for the codes */
int max_code; /* largest code with non zero frequency */
} tree_desc;
extern tree_desc l_desc;
extern tree_desc d_desc;
extern tree_desc bl_desc;
extern ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
extern uch bl_order[BL_CODES];
/* The lengths of the bit length codes are sent in order of decreasing
* probability, to avoid transmitting the lengths for unused bit length codes.
*/
extern int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
extern int heap_len; /* number of elements in the heap */
extern int heap_max; /* element of largest frequency */
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
* The same heap array is used to build all trees.
*/
extern uch depth[2*L_CODES+1];
/* Depth of each subtree used as tie breaker for trees of equal frequency */
extern uch length_code[MAX_MATCH-MIN_MATCH+1];
/* length code for each normalized match length (0 == MIN_MATCH) */
extern uch dist_code[512];
/* distance codes. The first 256 values correspond to the distances
* 3 .. 258, the last 256 values correspond to the top 8 bits of
* the 15 bit distances.
*/
extern int base_length[LENGTH_CODES];
/* First normalized length for each code (0 = MIN_MATCH) */
extern int base_dist[D_CODES];
/* First normalized distance for each code (0 = distance of 1) */
#define l_buf inbuf
/* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */
/* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */
extern uch flag_buf[(LIT_BUFSIZE/8)];
/* flag_buf is a bit array distinguishing literals from lengths in
* l_buf, thus indicating the presence or absence of a distance.
*/
extern unsigned last_lit; /* running index in l_buf */
extern unsigned last_dist; /* running index in d_buf */
extern unsigned last_flags; /* running index in flag_buf */
extern uch flags; /* current flags not yet saved in flag_buf */
extern uch flag_bit; /* current bit used in flags */
/* bits are filled in flags starting at bit 0 (least significant).
* Note: these flags are overkill in the current code since we don't
* take advantage of DIST_BUFSIZE == LIT_BUFSIZE.
*/
extern ulg opt_len; /* bit length of current block with optimal trees */
extern ulg static_len; /* bit length of current block with static trees */
extern ulg compressed_len; /* total bit length of compressed file */
extern ulg input_len; /* total byte length of input file */
/* input_len is for debugging only since we can get it by other means. */
extern ush *file_type; /* pointer to UNKNOWN, BINARY or ASCII */
extern int *file_method; /* pointer to DEFLATE or STORE */
#ifdef DEBUG
extern ulg bits_sent; /* bit length of the compressed data */
extern long isize; /* byte length of input file */
#endif
extern long block_start; /* window offset of current block */
extern unsigned strstart; /* window offset of current string */
#ifndef DEBUG
# define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len)
/* Send a code of the given tree. c and tree must not have side effects */
#else /* DEBUG */
# define send_code(c, tree) \
{ if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \
send_bits(tree[c].Code, tree[c].Len); }
#endif
#define d_code(dist) \
((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. dist_code[256] and dist_code[257] are never
* used.
*/
#define MAX(a,b) (a >= b ? a : b)
/* the arguments must not have side effects */
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
/* lgk make this function inline and use registers since it gets called 150K
times in a little example */
_inline int ct_tally (dist, lc)
register int dist; /* distance of matched string */
register int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
{
l_buf[last_lit++] = (uch)lc;
if (dist == 0) {
/* lc is the unmatched char */
dyn_ltree[lc].Freq++;
} else {
/* Here, lc is the match length - MIN_MATCH */
dist--; /* dist = match distance - 1 */
Assert((ush)dist < (ush)MAX_DIST &&
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
(ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match");
dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
dyn_dtree[d_code(dist)].Freq++;
d_buf[last_dist++] = (ush)dist;
flags |= flag_bit;
}
flag_bit <<= 1;
/* Output the flags if they fill a byte: */
if ((last_lit & 7) == 0) {
flag_buf[last_flags++] = flags;
flags = 0, flag_bit = 1;
}
/* Try to guess if it is profitable to stop the current block here */
if (level > 2 && (last_lit & 0xfff) == 0) {
/* Compute an upper bound for the compressed length */
register ulg out_length = (ulg)last_lit*8L;
register ulg in_length = (ulg)strstart-block_start;
register int dcode;
for (dcode = 0; dcode < D_CODES; dcode++) {
out_length += (ulg)dyn_dtree[dcode].Freq*(5L+extra_dbits[dcode]);
}
out_length >>= 3;
Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
last_lit, last_dist, in_length, out_length,
100L - out_length*100L/in_length));
if (last_dist < last_lit/2 && out_length < in_length/2) return 1;
}
return (last_lit == LIT_BUFSIZE-1 || last_dist == DIST_BUFSIZE);
/* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
*/
}